#region Copyright
/*
Copyright Notice: 
Use of this file, in source or binary form, is subject to the terms and conditions set forth 
in the included license.txt file.
*/
#endregion

/* This is a customised template.
 * It overrides some optional methods from EntityMap to allow for testing 
 * with Mocks and fast object creation. Search for #custom# below. 
 */

#set($entity = $Neo.Entity)

#if($Neo.Entity.Namespace)
namespace ${Neo.Entity.Namespace}.Models
{
#end

	#region Using statements

	using System;
	using System.Collections;
	using System.Collections.Generic;
	using System.Data;
	using Neo.Core;
	using Expergent;
	using Expergent.Neo;
	using Castle.Components.Validator;
	#if($entity.Relationships.Count > 0)
	using Neo.Core.Util;
	#end
	using Neo.Framework;
	#foreach($ns in $entity.UsedNamespaces)
	#if($ns != $entity.Namespace)
	using $ns;
	#end
	#end

	#endregion

	#region I${entity.ClassName}

	/// <summary>
	/// Generated table specific Interface </summary>
	/// <remarks> This Interface is generated by the Neo Framework. Make changes to NeoSupport.vtl.</remarks>
	public partial interface I${entity.ClassName}
	{
	#foreach($rel in $entity.ToManyRelationships)
		/// <summary>
		/// A collection of ${rel.ForeignEntity.ClassName} objects referencing this instance.</summary>
		/// <remarks> Objects referencing this instance.</remarks>
		ObjectRelation<${rel.ForeignEntity.ClassName}> ${rel.DotNetName} { get; }

	#end
		
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
		/// <summary>
		/// Property $attribute.DotNetName - #if($attribute.Description.Length == 0)No Description #else $attribute.Description #end</summary>
		/// <remarks> Database Path: ${Neo.Model.Name}.${Neo.Entity.TableName}.${attribute.ColumnName}.</remarks>
		/// <value> $attribute.DotNetType. </value>
	#if($attribute.DotNetType == "System.String")
		$attribute.DotNetType $attribute.DotNetName {get; set;}
	#else
		$attribute.DotNetType? $attribute.DotNetName {get; set;}
	#end

	#end
	#end

	#foreach($rel in $entity.ToOneRelationships)
		/// <summary>
		/// Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</summary>
		/// <remarks> Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</remarks>
		/// <value> $rel.ForeignEntity.ClassName. </value>
		$rel.ForeignEntity.ClassName $rel.DotNetName {get; set;}

	#end
	}

	#endregion

	#region ${entity.ClassName}

	/// <summary>
	/// Generated table specific Base Class </summary>
	/// <remarks> This class is generated by the Neo Framework. Make changes to NeoSupport.vtl.</remarks>
	[Serializable]
	public partial class ${entity.ClassName} : RulesEnabledEntityObject, I${entity.ClassName}
	{
	#foreach($rel in $entity.ToManyRelationships)
		/// <summary>
		/// A collection of ${rel.ForeignEntity.ClassName} objects referencing this instance.</summary>
		/// <remarks> Objects referencing this instance.</remarks>
		public ObjectRelation<${rel.ForeignEntity.ClassName}> ${rel.DotNetName}
		{
			get {return _${rel.DotNetName};}
		}
		
		private ObjectRelation<${rel.ForeignEntity.ClassName}> _${rel.DotNetName};
		
	#end

	#foreach($rel in $entity.ManyToManyRelationships)
		/// <summary>
		/// A collection of ${rel.ForeignEntity.ClassName} objects referencing this instance.</summary>
		/// <remarks> Objects referencing this instance.</remarks>
		public ManyToManyRelation<${rel.OtherEntity}> ${rel.OtherRelationName}
		{
			get {return _${rel.OtherRelationName};}
		}
		
		private ManyToManyRelation<${rel.OtherEntity}> _${rel.OtherRelationName};
		
	#end	       
		internal ${entity.ClassName}(System.Data.DataRow aRow, Neo.Core.ObjectContext aContext) : base(aRow, aContext)
		{
	#foreach($rel in $entity.ToManyRelationships)
			_${rel.DotNetName} = new ObjectRelation<${rel.ForeignEntity.ClassName}>(this, "$rel.DotNetName");
	#end
	#foreach($rel in $entity.ManyToManyRelationships)
			_${rel.OtherRelationName} = new ManyToManyRelation<${rel.OtherEntity}>(this, typeof($rel.ManyToManyEntity), "$rel.ThisRelationName", "$rel.OtherRelationName");
	#end
		}
		
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
		/// <summary>
		/// Property $attribute.DotNetName - #if($attribute.Description.Length == 0)No Description #else $attribute.Description #end</summary>
		/// <remarks> Database Path: ${Neo.Model.Name}.${Neo.Entity.TableName}.${attribute.ColumnName}.</remarks>
		/// <value> $attribute.DotNetType. </value>
	#if($attribute.PropertyAttributes)
		[${attribute.PropertyAttributes}]
	#end 
	#if($attribute.DotNetType == "System.String")
		public virtual $attribute.DotNetType $attribute.DotNetName
		{
			get { return Row["$attribute.ColumnName"] as System.String; }
	#if($attribute.AllowChanges)
			set { Row["$attribute.ColumnName"] = (value != null) ? (object)value : (object)DBNull.Value; }
	#else
			set { if ($attribute.DotNetName == null ) Row["$attribute.ColumnName"] = (value != null) ? (object)value : (object)DBNull.Value; }
	#end	
	#elseif($attribute.DotNetType == "System.Byte[]")
    public virtual $attribute.DotNetType $attribute.DotNetName
		{
			get { return Row["$attribute.ColumnName"] as System.Byte[]; }
			set { Row["$attribute.ColumnName"] = (value != null) ? (object)value : (object)DBNull.Value; }
	#else
		public virtual $attribute.DotNetType? $attribute.DotNetName
		{
			get { object v = Row["$attribute.ColumnName"]; return ($attribute.DotNetType?)((v != DBNull.Value) ? v : null); }
	#if($attribute.AllowChanges)
			set { if (value.HasValue) Row["$attribute.ColumnName"] = value; else Row["$attribute.ColumnName"] = DBNull.Value; }
	#else
			set { if ($attribute.DotNetName == null ) { if (value.HasValue) Row["$attribute.ColumnName"] = value; else Row["$attribute.ColumnName"] = DBNull.Value; } }
	#end
	#end
		}    

	#end
	#end

	#foreach($rel in $entity.ToOneRelationships)
		/// <summary>
		/// Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</summary>
		/// <remarks> Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</remarks>
		/// <value> $rel.ForeignEntity.ClassName. </value>
		public virtual $rel.ForeignEntity.ClassName $rel.DotNetName
		{
			get { object fk = Row["$rel.LocalKey"]; return (fk == DBNull.Value) ? null : ($rel.ForeignEntity.ClassName)GetRelatedObject("$rel.ForeignEntity.TableName", fk); }
			set { SetRelatedObject(value, "$rel.LocalKey", "$rel.ForeignKey" ); }
		}

	#end
			/// <summary>
		/// Returns the value associated with the propName parameter.</summary>
		/// <remarks> You will need to cast the returned object into its native type upon return.</remarks>
		/// <param name="propName">String property name.</param>
		/// <returns> System.Object. </returns>
		public override object GetProperty(string propName)
		{
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
			if(propName == "$attribute.DotNetName") 
				return $attribute.DotNetName;
	#end
	#end
	#foreach($rel in $entity.ToOneRelationships)
			if(propName == "$rel.DotNetName") 
				return $rel.DotNetName;
	#end
	#foreach($rel in $entity.ToManyRelationships)
			if(propName == "$rel.DotNetName") 
				return $rel.DotNetName;
	#end
			return ExtendGetProperty(propName);
		}
		
		/// <summary>
		/// Sets the value associated with the propName parameter to the value specified.
		/// </summary>
		/// <param name="propName">String property name.</param>
		/// <param name="value">The value.</param>
		public override void SetProperty(string propName, object value)
		{
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
	#if($attribute.DotNetType == "System.String")
			if(propName == "$attribute.DotNetName") 
			{
				$attribute.DotNetName = (System.String)value;
				return;
			}
	#else
			if(propName == "$attribute.DotNetName") 
			{
				$attribute.DotNetName = ($attribute.DotNetType?)value;
				return;
			}
	#end
	#end
	#end
	#foreach($rel in $entity.ToOneRelationships)
			if(propName == "$rel.DotNetName") 
			{
				$rel.DotNetName = ($rel.ForeignEntity.ClassName)value;
				return;
			}
	#end
			ExtendSetProperty(propName, value);
		}
		
		/// <summary>
		/// Adds a set of facts for this instance to the list.
		/// </summary>
		/// <param name="list">The list.</param>
		/// <param name="parent">The parent.</param>
		protected override void MakeFacts(List<WME> list, string parent)
		{
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
			list.Add(new WME(new EntityObjectTerm(this), MakePredicate(parent, "$attribute.DotNetName"), $attribute.DotNetName));
	#end
	#end
	#foreach($rel in $entity.ToOneRelationships)
			list.Add(new WME(new EntityObjectTerm(this), MakePredicate(parent, "$rel.DotNetName"), $rel.DotNetName));
	#end
	#foreach($rel in $entity.ToManyRelationships)
			list.Add(new WME(new EntityObjectTerm(this), MakePredicate(parent, "$rel.DotNetName"), $rel.DotNetName));
	#end
			ExtendMakeFacts(list, parent);
			myFactsHaveBeenAsserted = true;
		}

		/// <summary>
		/// Gets the default sort order.
		/// </summary>
		/// <value>The sort order.</value>
		public static PropertyComparer DefaultSortOrder
		{
			get
			{
	#if($entity.DefaultProperty)
				return new PropertyComparer("$entity.DefaultProperty", SortDirection.Ascending);
	#else
				return new PropertyComparer("${entity.PkColumns.get_Item(0).PropertyName}", SortDirection.Ascending);
	#end      
			}    
		}

	#if($entity.ToManyRelationships.Count > 0)
		/// <summary>
		/// Ensures related tables are loaded into memory for a cascaded delete.</summary>
		/// <remarks> Deletes related tables entries when cascade is specified.</remarks>
		public override void Delete() 
		{
	#foreach($rel in $entity.ToManyRelationships)
	#if($rel.DeleteRule.ToString() == "Cascade")
			${rel.DotNetName}.Touch();
			while (${rel.DotNetName}.Count > 0)
			{
				${rel.DotNetName}[0].Delete();
			}
	#end
	#end
			base.Delete();
		}
	#end
		
		/// <summary>
		/// Populates the EntityObject from the specified surrogate.
		/// </summary>
		/// <param name="surrogate">The surrogate.</param>
		public void Populate(${entity.ClassName}Surrogate surrogate)
		{
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden && !$attribute.IsPkColumn)
			${attribute.DotNetName} = surrogate.${attribute.DotNetName};
	#end
	#end
		}
	}

	#endregion

	#region ${entity.ClassName}Template

	/// <summary>
	/// Generated table specific Query Template Class </summary>
	/// <remarks> A Query Template for ${entity.ClassName} operations. </remarks>
	public class ${entity.ClassName}Template : QueryTemplate
	{

		/// <summary>
		/// Constructor </summary>
		/// <remarks> Public Constructor.</remarks>
		/// <param name="anEntityMap">IEntityMap instance.</param>
		public ${entity.ClassName}Template(IEntityMap anEntityMap) : base(anEntityMap)
		{
		}
		
	#foreach($attributes in $entity.Attributes)
	#if(!$attributes.IsHidden)
		/// <summary>
		/// Property $attributes.DotNetName - #if($attributes.Description.Length == 0)No Description #else $attributes.Description #end</summary>
		/// <remarks> Database Path: ${Neo.Entity.Model.Name}.${Neo.Entity.TableName}.${attributes.ColumnName}.</remarks>
		/// <value> $attributes.DotNetType. </value>
		public $attributes.DotNetType $attributes.DotNetName
		{
			get { return ($attributes.DotNetType)QueryValues["$attributes.DotNetName"]; }
			set { QueryValues["$attributes.DotNetName"] = value; }
		}

	#end
	#end
	#foreach($rel in $entity.ToOneRelationships)
		/// <summary>
		/// Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</summary>
		/// <remarks> Gets or sets the $rel.ForeignEntity.ClassName object.</remarks>
		/// <value> $rel.ForeignEntity.ClassName. </value>
		public $rel.ForeignEntity.ClassName $rel.DotNetName
		{
			get { return ($rel.ForeignEntity.ClassName)QueryValues["$rel.DotNetName"]; }
			set { QueryValues["$rel.DotNetName"] = value; }
		}

	#end
	               
	}

	#endregion

	#region ${entity.ClassName}Factory

	/// <summary>
	/// Factory class for the creation of ${entity.ClassName} objects.</summary>
	public class ${entity.ClassName}Factory : Neo.Framework.GenericObjectFactory<$entity.ClassName>
	{

		/// <summary>
		/// Constructor requiring an ObjectContext parameter.</summary>
		/// <remarks> Main entry point for the retrieval and creation of new ${entity.ClassName} objects.</remarks>
		/// <param name="context">ObjectContext.</param>
		public ${entity.ClassName}Factory(ObjectContext context) : base(context, typeof($entity.ClassName))
		{
		}

	#if($entity.IdMethod.ToString == "None")
	#if($entity.PrimaryKeyIsForeignKey)
	#foreach($combination in $entity.RelationshipSetsForColumns($entity.PkColumns))
		/// <summary>
		/// Create new $entity.ClassName object.</summary>
		/// <remarks>IdMethod = $entity.IdMethod.ToString(), PrimaryKeyIsForeignKey = $entity.PrimaryKeyIsForeignKey.ToString(), RelationshipSetsForColumns = $entity.RelationshipSetsForColumns($entity.PkColumns).Length.</remarks>
	#foreach($rel in $combination)#set( $pnum = $velocityCount - 1)
		/// <param name="arg${pnum}">$rel.ForeignEntity.ClassName.</param>
	#end
		/// <returns> $entity.ClassName </returns>
		public $entity.ClassName CreateObject(#foreach($rel in $combination)#set( $pnum = $velocityCount - 1)#if( $pnum > 0), #end$rel.ForeignEntity.ClassName arg${pnum}#end)
		{
			return ($entity.ClassName)base.CreateObject(new object[] {#foreach($rel in $combination)#set( $pnum = $velocityCount - 1)#if( $pnum > 0),#end arg${pnum}.Row["$rel.ForeignKey"]#end } );
		}

	#end
	#else
		/// <summary>
		/// Create new $entity.ClassName object.</summary>
		/// <remarks>IdMethod = $entity.IdMethod.ToString(), PrimaryKeyIsForeignKey = $entity.PrimaryKeyIsForeignKey.ToString(), RelationshipSetsForColumns = $entity.RelationshipSetsForColumns($entity.PkColumns).Length.</remarks>
	#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)
		/// <param name="arg${pnum}">#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.Description#end.</param>
	#end	
		/// <returns> $entity.ClassName </returns>
		public $entity.ClassName CreateObject(#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $pnum > 0), #end#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.DotNetType#end arg${pnum}#end)
		{
			return ($entity.ClassName)base.CreateObject(new object[] {#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $entity.ColumnIsForeignKey($column.ColumnName)) arg${pnum}.Row["$entity.RelationshipForAttribute($column).ForeignKey"]#else arg${pnum}#end#if( $velocityCount < $entity.PkColumns.Count),#end#end } );
		}
		
	#end
	#else	 
		/// <summary>
		/// Create new $entity.ClassName object.</summary>
		/// <remarks>IdMethod = $entity.IdMethod.ToString(), PrimaryKeyIsForeignKey = $entity.PrimaryKeyIsForeignKey.ToString(), RelationshipSetsForColumns = $entity.RelationshipSetsForColumns($entity.PkColumns).Length.</remarks>
		/// <returns> $entity.ClassName </returns>
		public $entity.ClassName CreateObject()
		{
			return ($entity.ClassName)base.CreateObject(null);
		}
		
	#end 

		/// <summary>
		/// Find a specified $entity.ClassName object.</summary>
		/// <remarks> Requires Primary Key values and/or parent object instances.</remarks>
	#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)
		/// <param name="arg${pnum}">#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.Description#end.</param>
	#end
		/// <returns> $entity.ClassName </returns>
		public $entity.ClassName FindObject(#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $pnum > 0), #end#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.DotNetType#end arg${pnum}#end)
		{
			return ($entity.ClassName)base.FindObject(new object[] {#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $entity.ColumnIsForeignKey($column.ColumnName)) arg${pnum}.Row["$entity.RelationshipForAttribute($column).ForeignKey"]#else arg${pnum}#end#if( $velocityCount < $entity.PkColumns.Count),#end#end } );
		}

		///<summary>
		///Find a specified $entity.ClassName object.</summary>
		///<remarks> Requires Primary Key values and/or parent object instances.</remarks>
	#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)
		///<param name="arg${pnum}">#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.Description#end.</param>
	#end
		///<returns> $entity.ClassName </returns>
		public $entity.ClassName FindObjectByPK(#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $pnum > 0),#end $column.DotNetType arg${pnum} #end)
		{
			return ($entity.ClassName) base.FindObject( new object[] { #foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1) arg${pnum}#if( $velocityCount < $entity.PkColumns.Count),#end#end } );
		}
		
	#set ($doNullable = false)
	#foreach($column in $entity.PkColumns)
	#if ($column.DotNetType != "System.String")
	#set ($doNullable = true)
	#end
	#end

	#if ($doNullable)
		///<summary>
		///Find a specified $entity.ClassName object.</summary>
		///<remarks> Requires Primary Key values and/or parent object instances.</remarks>
	#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)
		///<param name="arg${pnum}">#if( $entity.ColumnIsForeignKey($column.ColumnName))$entity.RelationshipForAttribute($column).ForeignEntity.ClassName#else$column.Description#end.</param>
	#end
		///<returns> $entity.ClassName </returns>
		public $entity.ClassName FindObjectByPK(#foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1)#if( $pnum > 0),#end ${column.DotNetType}#if ($column.DotNetType != "System.String")?#end arg${pnum} #end)
		{
			return ($entity.ClassName) base.FindObject( new object[] { #foreach($column in $entity.PkColumns)#set( $pnum = $velocityCount - 1) arg${pnum}#if ($column.DotNetType != "System.String").Value#end#if( $velocityCount < $entity.PkColumns.Count),#end#end } );
		}
	#end
		
		/// <summary>
		/// Return the correct Query Template for the $entity.ClassName object.</summary>
		/// <remarks> A query template is used for creating SQL like queries, in a more OO fashion.</remarks>
		/// <returns> ${entity.ClassName}Template </returns>
		public ${entity.ClassName}Template GetQueryTemplate()
		{
			return new ${entity.ClassName}Template(EntityMap);
		}
		
		/// <summary>
		/// SQL like query to find and return an object.</summary>
		/// <remarks> For example: ...FindFirst("TitleAuthors.(Title = {0} or Title.Publisher = {1})", title, publisher).</remarks>
		/// <param name="qualifierFormat">String.</param>
		/// <param name="parameters">params object[].</param>
		/// <returns> ${entity.ClassName}. </returns>
		public override ${entity.ClassName} FindFirst(string qualifierFormat, params object[] parameters)
		{
			ObjectList<$entity.ClassName> results = FindWithLimit(1, qualifierFormat, parameters);
			return (results.Count > 0) ? results[0] : null;
		}

		/// <summary>
		/// SQL like query to find and return an object.</summary>
		/// <remarks> For example: ...FindFirst("TitleAuthors.(Title = {0} or Title.Publisher = {1})", title, publisher).</remarks>
		/// <param name="q">The Qualifier.</param>
		/// <returns>${entity.ClassName}</returns>
		public override ${entity.ClassName} FindFirst(Qualifier q)
		{
			FetchSpecification f = new FetchSpecification(EntityMap, q, 1);
			ObjectList<$entity.ClassName> result = Find(f);
			return result.Count > 0 ? result[0]: null;
		}
	}

	#endregion

	#region ${entity.ClassName}EntityMap

	//  -------- Entity Map -----------------------------------------------------
	/// <summary>Creates the in memory version of the dataset for the ${entity.ClassName} DOM.</summary>
	/// <remarks>Generated by Neo Framework.</remarks>
	internal class ${entity.ClassName}Map : EntityMap
	{
		  /// <summary>Array of Primary Key column names.</summary>
		  /// <remarks>Primary Key columns.</remarks>
		private static readonly string[] pkcolumns = {#foreach($column in $entity.PkColumns)#if( $velocityCount > 1),#end "$column.ColumnName"#end };
		/// <summary>Array of Database column names.</summary>
		  /// <remarks>Database column names.</remarks>
		private static readonly string[] columns = {#foreach($column in $entity.Attributes)#if(!$attributes.IsHidden)#if( $velocityCount > 1),#end "$column.ColumnName"#end#end };
		/// <summary>Array of DOM object properties.</summary>
		  /// <remarks>DOM object properties.</remarks>
		private static readonly string[] attributes = {#foreach($column in $entity.Attributes)#if(!$attributes.IsHidden)#if( $velocityCount > 1),#end "$column.DotNetName"#end#end };
		/// <summary>Array of Related Object names.</summary>
		  /// <remarks>Related Object names.</remarks>
		private static readonly string[] relations = {#foreach($rel in $entity.Relationships)#if( $velocityCount > 1),#end "$rel.DotNetName"#end };

		private Type concreteObjectType = typeof($entity.ClassName);

		  /// <summary>Property ObjectType.</summary>
		  /// <remarks>Returns the DOM's Type.</remarks>
		  /// <value>System.Type.</value>
		public override System.Type ObjectType
		{
			get { return typeof($entity.ClassName); }
		}
	    
		/// <summary>Property ObjectType.</summary>
		  /// <remarks>Returns the DOM's Type.</remarks>
		  /// <value>System.Type.</value>
		public override System.Type ConcreteObjectType
		{
			get { return concreteObjectType; }										 /* #custom# overridden */
			set { concreteObjectType = value; Factory.AddCustomType(value, this); }  /* #custom# overridden */
		}
	    
		/// <summary>Property TableName.</summary>
		  /// <remarks>Returns database table name.</remarks>
		  /// <value>string.</value>
		public override string TableName
		{
			get { return "${entity.TableName}"; }
		}
	    
		/// <summary>Property PrimaryKeyColumns.</summary>
		/// <remarks>Array of Primary Key column names.</remarks>
		/// <value>string[].</value>
		public override string[] PrimaryKeyColumns
		{
			get { return pkcolumns; }
		}

		/// <summary>Property Columns.</summary>
		/// <remarks>Array of Database column names.</remarks>
		/// <value>string[].</value>
		public override string[] Columns
		{
			get { return columns; }
		}

		/// <summary>Property Attributes.</summary>
		/// <remarks>Array of DOM object properties.</remarks>
		/// <value>string[].</value>
		public override string[] Attributes
		{
			get { return attributes; }
		}

		/// <summary>Property Relations.</summary>
		/// <remarks>Array of Related Object names.</remarks>
		/// <value>string[].</value>
		public override string[] Relations
		{
			get { return relations; }
		}

		/// <summary>Generates a Hashtable, keyed by Object Name, or information regarding related objects.</summary>
		/// <remarks>Related Objects.</remarks>
		/// <returns>IDictionary.</returns>
  		protected override IDictionary GetRelationInfos()
		{
    		IDictionary infos = new Hashtable($entity.Relationships.Count);
	 #foreach($rel in $entity.Relationships)
	 #if($rel.Direction.ToString == "Parent")
			infos.Add("$rel.DotNetName", new RelationInfo(Factory, typeof($rel.LocalEntity.ClassName), typeof($rel.ForeignEntity.ClassName), "$rel.LocalKey", "$rel.ForeignKey"));
	#else
			infos.Add("$rel.DotNetName", new RelationInfo(Factory, typeof($rel.ForeignEntity.ClassName), typeof($rel.LocalEntity.ClassName), "$rel.ForeignKey", "$rel.LocalKey"));
	#end
	#end
			return infos;    	
		}
	    
		/// <summary>Based upon the model specified Id Method, returns the proper PkInitializer.</summary>
		/// <remarks>The object used to create a new PK value.</remarks>
		/// <returns>IPkInitializer.</returns>
		public override IPkInitializer GetPkInitializer()
		{
	#if($entity.IdMethod.ToString == "None")
			return new UserPkInitializer();
	#elseif($entity.IdMethod.ToString == "Native")
			return new NativePkInitializer();
	#elseif($entity.IdMethod.ToString == "IdBroker")
			return new IdBrokerPkInitializer();
	#elseif($entity.IdMethod.ToString == "Guid")
			return new GuidPkInitializer();
	#end
		}
	    
		/// <summary>Creates a new instance of ${entity.ClassName}.</summary>
		/// <remarks>Create new ${entity.ClassName}.</remarks>
		/// <param name="row">DataRow.</param>
		/// <param name="context">ObjectContext.</param>
		/// <returns>IEntityObject.</returns>
		public override IEntityObject CreateInstance(DataRow row, ObjectContext context) /* #custom# overridden */
		{
			if(ConcreteObjectType != ObjectType)
				return base.CreateInstance(row, context);
			return new ${entity.ClassName}(row, context);
		}
	    
		/// <summary>Generates the in memory dataset.</summary>
		/// <remarks>Called by the Factory object.</remarks>
		/// <param name="table">DataTable.</param>
		protected override void WriteBasicSchema(DataTable table)
		{
			DataColumn		c;
			
	#foreach($attributes in $entity.Attributes)
			c = table.Columns.Add("$attributes.ColumnName", typeof($attributes.DotNetType));
	#if($attributes.IsPkColumn)
	#if($entity.PkColumns.Count == 1) 
			c.Unique = true;
	#end
	#if(($entity.IdMethod.ToString == "Native") || ($entity.IdMethod.ToString == "IdBroker"))
			c.AutoIncrement = true; c.AutoIncrementSeed = c.AutoIncrementStep = -1;
	#end
	#end
	#if($attributes.AllowsNull)
			c.AllowDBNull = true;
	#end
	#if($attributes.DefaultValue)
	#if($attributes.DefaultValue.Equals("now"))
			c.DefaultValue = Convert.ChangeType(System.DateTime.Now, typeof($attributes.DotNetType));
	#else
			c.DefaultValue = Convert.ChangeType("$attributes.DefaultValue", typeof($attributes.DotNetType));
	#end
	#end
	#if($attributes.IsSQLTextColumn)
			c.ExtendedProperties.Add("LockStrategy","NONE");
	#end
	#end
			table.PrimaryKey = new DataColumn[] {#foreach($column in $entity.PkColumns)#if( $velocityCount > 1),#end table.Columns["$column.ColumnName"]#end };
		}
		
	#if($entity.Relationships.Count > 0)
		/// <summary>Generates the dataset relationships.</summary>
		/// <remarks>Dataset Relationships.</remarks>
		/// <param name="table">DataTable.</param>
		protected override void WriteRelations(DataTable table)
		{
			DataRelation r;
			
	#foreach($rel in $entity.Relationships)
	#if($rel.Direction.ToString == "Parent") ## yes, that's how you compare enums...
			if(table.DataSet.Relations["${rel.LocalEntity.TableName}*${rel.ForeignEntity.TableName}.${rel.ForeignKey}"] == null)
			{
				r = table.DataSet.Relations.Add("${rel.LocalEntity.TableName}*${rel.ForeignEntity.TableName}.${rel.ForeignKey}", 
						table.DataSet.Tables["$rel.LocalEntity.TableName"].Columns["$rel.LocalKey"],
						table.DataSet.Tables["$rel.ForeignEntity.TableName"].Columns["$rel.ForeignKey"]);
				r.ChildKeyConstraint.UpdateRule = $rel.DotNetUpdateRule;
				r.ChildKeyConstraint.DeleteRule = $rel.DotNetDeleteRule;
			}
	#else
			if(table.DataSet.Relations["${rel.ForeignEntity.TableName}*${rel.LocalEntity.TableName}.${rel.LocalKey}"] == null)
			{
				r = table.DataSet.Relations.Add("${rel.ForeignEntity.TableName}*${rel.LocalEntity.TableName}.${rel.LocalKey}", 
						table.DataSet.Tables["$rel.ForeignEntity.TableName"].Columns["$rel.ForeignKey"],
						table.DataSet.Tables["$rel.LocalEntity.TableName"].Columns["$rel.LocalKey"]);
	#set($rel = $rel.InverseRelationship)
	#if($rel)
				r.ChildKeyConstraint.UpdateRule = $rel.DotNetUpdateRule;
				r.ChildKeyConstraint.DeleteRule = $rel.DotNetDeleteRule;
	#else
				r.ChildKeyConstraint.UpdateRule = Rule.Cascade;
				r.ChildKeyConstraint.DeleteRule = Rule.SetNull; /* child and can't find inverse */
	#end
			}
	#end			
	#end
		}
	#end
	}

	#endregion

	#region ${Neo.Entity.ClassName}Surrogate

	/// <summary>Represents an entity object disconnected from the database.</summary>
	/// <remarks>
	///   <para>Database Path: ${Neo.Entity.Model.Name}.${Neo.Entity.TableName}.</para>
	/// </remarks>
	public partial class ${Neo.Entity.ClassName}Surrogate : EntityObjectSurrogate, I${entity.ClassName}
	{
		/// <summary>Default constructor.</summary>
		public ${Neo.Entity.ClassName}Surrogate()
		{
	#foreach($attribute in $entity.Attributes)#if(!$attribute.IsHidden || ($attribute.IsHidden && $attribute.IsPkColumn))#if($attribute.DefaultValue && $attribute.DefaultValue != "")
	#if($attribute.DotNetType.Equals("System.String"))
			_${attribute.DotNetName.ToLower()} = "${attribute.DefaultValue}";
	#end
	#if($attribute.DotNetType.Equals("System.DateTime"))
	#if($attribute.DefaultValue.Equals("now"))
			_${attribute.DotNetName.ToLower()} = System.DateTime.Now;
	#else
			_${attribute.DotNetName.ToLower()} = System.Convert.ToDateTime("${attribute.DefaultValue}");
	#end
	#else
			_${attribute.DotNetName.ToLower()} = ($attribute.DotNetType)System.Convert.ChangeType("${attribute.DefaultValue}", typeof($attribute.DotNetType));
	#end
	#end##end has default value
	#end##end hidden check
	#end##end foreach
		}
	    
	    
	    
		/// <summary>
		/// Initializes a new instance of the <see cref="${Neo.Entity.ClassName}Surrogate"/> class.
		/// </summary>
		/// <param name="entity">The entity.</param>
		public ${Neo.Entity.ClassName}Surrogate(${Neo.Entity.ClassName} entity)
		{
	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
			${attribute.DotNetName} = entity.${attribute.DotNetName};
	#end
	#end
		}

#foreach($rel in $entity.ToManyRelationships)
		/// <summary>
		/// A collection of ${rel.ForeignEntity.ClassName} objects referencing this instance.</summary>
		/// <remarks> Objects referencing this instance.</remarks>
		public ObjectRelation<${rel.ForeignEntity.ClassName}> ${rel.DotNetName}
		{
			get {return _${rel.DotNetName};}
			set {_${rel.DotNetName} = value;}
		}
		
		private ObjectRelation<${rel.ForeignEntity.ClassName}> _${rel.DotNetName};

#end
	
#foreach($rel in $entity.ToOneRelationships)
		/// <summary>
		/// Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</summary>
		/// <remarks> Property $rel.DotNetName - gets or sets the $rel.ForeignEntity.ClassName object with a one-to-one relationship to this instance.</remarks>
		/// <value> $rel.ForeignEntity.ClassName. </value>
		public virtual $rel.ForeignEntity.ClassName $rel.DotNetName
		{
			get { return _${rel.DotNetName}; }
			set { _${rel.DotNetName} = value; }
		}
		
		private $rel.ForeignEntity.ClassName _${rel.DotNetName};
#end
	
		/// <summary>
		/// Updates the entity with the values contained within the surrogate.
		/// </summary>
		/// <param name="entity">The entity.</param>
		public void BindObjectInstance(${Neo.Entity.ClassName} entity)
		{
	#foreach($attribute in $entity.Attributes)
	#if($attribute.IsPkColumn == false && $attribute.IsHidden == false)
			entity.${attribute.DotNetName} = ${attribute.DotNetName};
	#end
	#end
		}

	#foreach($attribute in $entity.Attributes)
	#if(!$attribute.IsHidden)
	#if($attribute.DotNetType == "System.String")
		/// <summary>
		/// Property $attribute.DotNetName - #if($attribute.Description.Length == 0)No Description #else $attribute.Description #end</summary>
		/// <remarks> Database Path: ${Neo.Model.Name}.${Neo.Entity.TableName}.${attribute.ColumnName}.</remarks>
		/// <value> $attribute.DotNetType. </value>
	#if($attribute.PropertyAttributes)
		[${attribute.PropertyAttributes}]
	#end   
		public $attribute.DotNetType ${attribute.DotNetName}
		{
    		get {return _${attribute.DotNetName.ToLower()};}
	#if($attribute.IsPkColumn)
			set {_${attribute.DotNetName.ToLower()} = value;}
	#else
    		set {_${attribute.DotNetName.ToLower()} = value;}
	#end
		}

		private $attribute.DotNetType _${attribute.DotNetName.ToLower()};
		
	#else
		/// <summary>
		/// Property $attribute.DotNetName - #if($attribute.Description.Length == 0)No Description #else $attribute.Description #end</summary>
		/// <remarks> Database Path: ${Neo.Model.Name}.${Neo.Entity.TableName}.${attribute.ColumnName}.</remarks>
		/// <value> $attribute.DotNetType. </value>
	#if($attribute.PropertyAttributes)
		[${attribute.PropertyAttributes}]
	#end 
		public $attribute.DotNetType? ${attribute.DotNetName}
		{
    		get {return _${attribute.DotNetName.ToLower()};}
	#if($attribute.IsPkColumn)
			set {_${attribute.DotNetName.ToLower()} = value;}
	#else
    		set {_${attribute.DotNetName.ToLower()} = value;}
	#end
		}

		private $attribute.DotNetType? _${attribute.DotNetName.ToLower()};
		
	#end
	#end
	#end

	#foreach($rel in $entity.ToOneRelationships)
		/// <summary>
		/// Property ${rel.DotNetName}List - gets or sets a list of $rel.ForeignEntity.ClassName objects upon which this entity depends.</summary>
		/// <remarks> Used mostly to populate the select controls on the view side. Returns the list sorted by the default property, if one is defined.</remarks>
		/// <value> An ObjectList of  $rel.ForeignEntity.ClassName. </value>
		public ObjectList<${rel.ForeignEntity.ClassName}> ${rel.DotNetName}List
		{
    		get 
    		{
	#if( ${rel.ForeignEntity.DefaultProperty} && ${rel.ForeignEntity.DefaultProperty} != "")    
				if (_${rel.DotNetName.ToLower()}List != null)
				{
					_${rel.DotNetName.ToLower()}List.Sort("${rel.ForeignEntity.DefaultProperty}", SortDirection.Ascending);
				}
	#end
				return _${rel.DotNetName.ToLower()}List;  
    		}
    		set {_${rel.DotNetName.ToLower()}List = value;}
		}

		private ObjectList<${rel.ForeignEntity.ClassName}> _${rel.DotNetName.ToLower()}List;
			
	#end

		/// <summary>
		/// Binds the surrogate values to the search template.
		/// </summary>
		/// <param name="emptyTemplate">The empty template.</param>
		public void BindToSearchTemplate(${Neo.Entity.ClassName}Template emptyTemplate)
		{
	#foreach($rel in $entity.ToOneRelationships)

	#foreach($at in $rel.LocalEntity.Attributes)
	#if($at.ColumnName == $rel.LocalKey)
	#if(!$at.IsHidden)
	#if($at.DotNetType == "System.String")
			if (this.${at.PropertyName} != null)
				emptyTemplate.${at.PropertyName} = this.${at.PropertyName};
	#else
			if (this.${at.PropertyName} != null)
				emptyTemplate.${at.PropertyName} = this.${at.PropertyName}.Value;
	#end
	#end
	#end
	#end
	#end
		}

	}
	#endregion

#if($Neo.Entity.Namespace)
}
#end

